-
Notifications
You must be signed in to change notification settings - Fork 10.4k
[Blazor] Use DynamicDependency to preserve KeyValuePair for WebAssembly trimming #63099
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Co-authored-by: javiercn <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds a default ILLink.Descriptors.xml file to the Microsoft.AspNetCore.Components.WebAssembly project to prevent the linker from trimming commonly used types during serialization in JS interop scenarios, specifically addressing issues with KeyValuePair<TKey, TValue>
being removed during WebAssembly trimming.
- Added ILLink.Descriptors.xml file to preserve
System.Collections.Generic.KeyValuePair<,>
type during linking - Updated project file to embed the descriptors file as a resource
- Provides automatic protection for common serialization scenarios without requiring manual developer configuration
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
File | Description |
---|---|
Microsoft.AspNetCore.Components.WebAssembly.csproj | Added EmbeddedResource entry to include the ILLink descriptors file |
ILLink.Descriptors.xml | New linker descriptor file that preserves KeyValuePair types from trimming |
why can't we use DynamicDependency for this? |
…eyValuePair preservation Co-authored-by: akoeplinger <[email protected]>
You're absolutely right! I've updated the implementation to use The attribute is now applied to the Commit: fc94643 |
src/Components/WebAssembly/WebAssembly/src/Services/DefaultWebAssemblyJSRuntime.cs
Outdated
Show resolved
Hide resolved
…dcoded strings Co-authored-by: pavelsavara <[email protected]>
src/Components/WebAssembly/WebAssembly/src/Services/DefaultWebAssemblyJSRuntime.cs
Outdated
Show resolved
Hide resolved
…for KeyValuePair Co-authored-by: pavelsavara <[email protected]>
NVM, I saw that we are already putting some of these things on the JS runtime |
@@ -37,6 +37,7 @@ private DefaultWebAssemblyJSRuntime() | |||
JsonSerializerOptions.Converters.Add(new ElementReferenceJsonConverter(ElementReferenceContext)); | |||
} | |||
|
|||
[DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(KeyValuePair<,>))] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move this to private DefaultWebAssemblyJSRuntime()
instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved the DynamicDependency attribute to the private constructor to consolidate all dynamic dependencies in one place. Commit: ba95337
Co-authored-by: javiercn <[email protected]>
src/Components/WebAssembly/WebAssembly/src/Microsoft.AspNetCore.Components.WebAssembly.csproj
Outdated
Show resolved
Hide resolved
…e.Components.WebAssembly.csproj Remove empty lines
It would be good to cover this with some E2E unit test. It should be configured to trim and validate that JSON can be de-serialized into a dictionary. The test project should not make reference to |
I don't feel that's necessary, at that point we are testing the linker behavior and adding an E2E test adds significant overhead to the codebase and the CI runs. |
@@ -31,6 +31,7 @@ internal sealed partial class DefaultWebAssemblyJSRuntime : WebAssemblyJSRuntime | |||
[DynamicDependency(nameof(BeginInvokeDotNet))] | |||
[DynamicDependency(nameof(ReceiveByteArrayFromJS))] | |||
[DynamicDependency(nameof(UpdateRootComponentsCore))] | |||
[DynamicDependency(DynamicallyAccessedMemberTypes.PublicConstructors, typeof(KeyValuePair<,>))] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot Use LinkerFlags.JsonSerialized
This change preserves
System.Collections.Generic.KeyValuePair<TKey, TValue>
during trimming to prevent runtime serialization issues in Blazor WebAssembly JS interop scenarios.Problem
When Blazor WebAssembly applications are trimmed, the linker may remove types that are used during runtime serialization for JS interop calls, particularly
System.Collections.Generic.KeyValuePair<TKey, TValue>
which is commonly used in dictionary serialization scenarios.Solution
Added a
DynamicDependency
attribute to theReadJsonSerializerOptions()
method to preserve only the public constructors of theKeyValuePair<,>
type:This approach:
typeof(KeyValuePair<,>)
for better type safety instead of hardcoded stringsDynamicDependency
extensivelyChanges
src/Components/WebAssembly/WebAssembly/src/Services/DefaultWebAssemblyJSRuntime.cs
- Added DynamicDependency attribute to preserve KeyValuePair public constructorsThis ensures that applications using the Components.WebAssembly package will automatically have these commonly needed types preserved during trimming without requiring developers to manually configure linker settings.
Fixes #63098.
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.